package webjoch.process.strategies.puzzles;

import java.awt.Graphics2D;

import org.rsbuddy.tabs.Inventory;

import com.rsbuddy.event.events.MessageEvent;
import com.rsbuddy.script.methods.Calculations;
import com.rsbuddy.script.methods.GroundItems;
import com.rsbuddy.script.methods.Npcs;
import com.rsbuddy.script.methods.Objects;
import com.rsbuddy.script.methods.Players;
import com.rsbuddy.script.methods.Widgets;
import com.rsbuddy.script.task.Task;
import com.rsbuddy.script.util.Filter;
import com.rsbuddy.script.wrappers.GameObject;
import com.rsbuddy.script.wrappers.GroundItem;
import com.rsbuddy.script.wrappers.Npc;

import webjoch.methods.Food;
import webjoch.methods.Items;
import webjoch.misc.Constants;
import webjoch.process.strategies.Puzzle;
import webjoch.wrappers.Room;

/**
 * 
 * @author Webjoch
 *
 */
public class ThreeStatues extends Puzzle{
	Room room;
	boolean solved = false;
	
	//TODO correct the statue id`s
	private final int WARIOR = 11050;
	private final int RANGER = 11044;
	private final int MAGER = 11042; // these is right
	private final int[] STATUES = {WARIOR, RANGER, MAGER};
	
	private final int SWORD = 17416;
	private final int BOW = 17418;
	private final int STAFF = 17420;
	private final int[] WEAPONS = {SWORD, BOW, STAFF};
	
	private final int[] CRUMBLING_WALL = {49647};
	private final int[] STONE_BLOCK = {17415};
	
	@Override
	public void setRoom(Room room) {
		this.room = room;
	}

	@Override
	public boolean isValid() {
		return getNpc(WARIOR) != null || getNpc(RANGER) != null || getNpc(MAGER) != null;
	}

	@Override
	public Type getType() {
		return Puzzle.Type.THREE_STATUES;
	}

	@Override
	public int loop(){
		if (Inventory.getCount(WEAPONS) == getStatueCount()){
			for (int i = 0; i < 3; i++){
				if (getNpc(STATUES[i]) == null || !Inventory.contains(WEAPONS[i])) continue;
				if (Calculations.distanceTo(getNpc(STATUES[i])) > 4){
					getNpc(STATUES[i]).getLocation().clickOnMap();
					return 1;
				}
				for (int i1 = 0; i1 < 100; i1++){
					if (!Players.getLocal().isMoving()) break;
					Task.sleep(50);
				}
				Inventory.getItem(WEAPONS[i]).interact("Use");
				if (getNpc(STATUES[i]).interact("Use")) Task.sleep(2000);
				return 1;
			}
		}
		
		GroundItem chisel = GroundItems.getNearest(Constants.CHISEL);
		if (!Inventory.containsOneOf(Constants.CHISEL) && chisel != null){
			if (Inventory.isFull()) Food.dropFood(1);
			Items.interact(chisel, "Take");
			return 1;
		}
		
		if (Inventory.getCount(STONE_BLOCK) < getStatueCount() - Inventory.getCount(WEAPONS)){
			GameObject crumblingWall = Objects.getNearest(CRUMBLING_WALL);
			if (crumblingWall != null){
				if (Calculations.distanceTo(crumblingWall) > 5){
					crumblingWall.getLocation().clickOnMap(); Task.sleep(800, 1500);
					return 1;
				}
				crumblingWall.interact("Mine"); Task.sleep(1000);
				for (int i = 0; i < 100; i++){
					if (Players.getLocal().getAnimation() < 0 || Inventory.getCount(STONE_BLOCK) >= 3 - Inventory.getCount(WEAPONS)) break;
					Task.sleep(40);
				}
				return 1;
			}
		}
		
		Inventory.getItem(STONE_BLOCK).interact("Carve");
		Task.sleep(1000);
		if (Widgets.getComponent(451, 0).isVisible()){
			for (int i = 0; i < 3; i++){
				if (getNpc(STATUES[i]) == null) continue;
				if (!Inventory.contains(WEAPONS[i])){
					Widgets.getComponent(451, i+1).click();
					Task.sleep(2000);
					break;
				}
			}
		}
		return 0;
	}

	public int getStatueCount(){
		int statuesCount = 0;
		for (int statue : STATUES){
			if (getNpc(statue) != null) statuesCount++;
		}
		return statuesCount;
	}
	
	@Override
	public int[] itemNeed() {
		return new int[] {Constants.PICKAXE[0], Constants.HAMMER[0]};
	}

	@Override
	public boolean isFinished(){
		if (Inventory.containsOneOf(WEAPONS)){
			for (int itemId : WEAPONS){
				if (Inventory.contains(itemId) && solved) Inventory.getItem(itemId).interact("Drop");
				//Expirimental change: added ' && solved' since it drops before solved
			}
		}
		for (Room solvedRoom : solvedRooms){
			if (solvedRoom.getLocation().equals(room.getLocation())) return true; 
		}
		if (solved) solvedRooms.add(room);
		return solved;
	}

	public GameObject getObject(final int id){
		return Objects.getNearest(new Filter<GameObject>(){
			public boolean accept(GameObject o) {
				return room.getArea().contains(o.getLocation()) && id == o.getId();
			}
		});
	}
	
	public Npc getNpc(final int id){
		return Npcs.getNearest(new Filter<Npc>(){
			public boolean accept(Npc o) {
				return room.getArea().contains(o.getLocation()) && id == o.getId();
			}
		});
	}

	@Override
	public void messageReceived(MessageEvent e) {
		if (e.getMessage().contains("hear a clicking sound")){
			solved = true;
		}
	}

	@Override
	public void onRepaint(Graphics2D g) {
		// TODO Auto-generated method stub
		
	}
}
